#!/usr/bin/tcl

  ###############################################################################
  # This command will calculate the gap required to generate a specified load
  # or frames per second rate.
  #
  # This test program does not set up streams to allow compatability with non
  # SmartMetrics cards.  It will not run on SmartMetrics only cards for that 
  # reason.
  # Will force speed to 100MHz with HTSetSpeed.  Will cause problems in situations
  # where autonegotiation is required.
  #
  # In all cases, the specifed load will only be valid at the speed and packet length
  # specified in the function call.
  #
  # Program runs back to back.  
  ###############################################################################
  
  # for Spirent Connect use package require...
  # package require smartlib
  
  # For standalone use source smartlib.tcl (path must reflect location on local system)
  #source smartlib.tcl
  
 # If smartlib.tcl is not loaded, attempt to locate it at the default location.
# The actual location is different on different platforms.
#if  {$tcl_platform(platform) == "windows"} {
#      set libPath "../../../../tcl/tclfiles/smartlib.tcl"
#} else {
#         set libPath "/root/TclAutoTest/lib/smartlib.tcl"
#}
# if "smartlib.tcl" is not loaded, try to source it from the default path

set libPath "/root/TclAutoTest/lib/smartlib.tcl"

if { ! [info exists __SMARTLIB_TCL__] } {
     if {[file exists $libPath]} {
          source $libPath
} else {

         #Enter the location of the "smartlib.tcl" file or enter "Q" or "q" to quit
         while {1} {

                     puts "Could not find the file $libPath."
                     puts "Enter the path of smartlib.tcl, or q to exit."

                     gets stdin libPath
                     if {$libPath == "q" || $libPath == "Q"} {
                          exit
                     }
                     if {[file exists $libPath]} {
                          source $libPath
                          break
                     }

         }
   }
}

#Define variables
set Hub 0

set Slot1 0
set Port1 5

set Slot2 2
set Port2 0
set Port3 1
 
    # You must know the speed and data length to set the load!
    # Use library constant for speed not numeric value
  set speed      $SPEED_100MHZ
  #set speed      $SPEED_10MHZ
    # we assume minimum length packet size but do not set it (see above)
  set dataLength 512
  
    # 125 frames per second
  set framesPerSecond 100
    # 10% load
  set loadPerCent 10
  
  ###############################################################################
  # Uses NSCalculateGap to set TX as Packets Per Second
  # Returns the GAP value needed to set the requested rate
  ###############################################################################
  proc setFramesPerSecond {H S P speed dataLength framesPerSecond} {
      set gap ""
      NSCalculateGap $::PPS_TO_GAP_BITS $speed $dataLength $framesPerSecond gap $H $S $P
      return $gap
  }
  ###############################################################################
  
  ###############################################################################
  # Uses NSCalculateGap to set TX as load percent
  # Returns the GAP value needed to set the requested rate
  ###############################################################################
  proc setLoad {H S P speed dataLength loadPercent} {
      set gap ""
      NSCalculateGap $::PERCENT_LOAD_TO_GAP_BITS $speed $dataLength $loadPercent gap $H $S $P
      return $gap
  }
  ###############################################################################
  
  
  ###############################################################################
  proc displayCount {H S P} {
  
    struct_new cs HTCountStructure
    after 100
    LIBCMD HTGetCounters cs $H $S $P
  
  puts "======================================================="
  puts "              Counter Data Card [expr $S +1]                |"
  puts "======================================================="
  puts "            Events (Total)    |     Rates (Per Second) |"
  puts "======================================================="
  puts "Tx Packets      [format "%12d" $cs(TmtPkt)] |            [format "%12d" $cs(TmtPktRate)] |"
  puts "Rx Packets      [format "%12d" $cs(RcvPkt)] |            [format "%12d" $cs(RcvPktRate)] |"
  puts "-------------------------------------------------------"
  puts "Recvd Trigger     [format "%12d" $cs(RcvTrig)] |            [format "%12d" $cs(RcvTrigRate)] |"
  puts "Collisions     [format "%12d" $cs(Collision)] |            [format "%12d" $cs(CollisionRate)] |"
  puts "-------------------------------------------------------"
  puts "CRC Errors     [format "%12d" $cs(CRC)] |            [format "%12d" $cs(CRCRate)] |"
  puts "Align Errors     [format "%12d" $cs(Align)] |            [format "%12d" $cs(AlignRate)] |"
  puts "-------------------------------------------------------"
  puts "Oversize     [format "%12d" $cs(Oversize)] |            [format "%12d" $cs(OversizeRate)] |"
  puts "Undersize     [format "%12d" $cs(Undersize)] |            [format "%12d" $cs(UndersizeRate)] |"
  puts "-------------------------------------------------------"
  
  }
  ###############################################################################
  
  
  ################################################################################
  # Check for existing link.  If linked, fall through and return.
  # If not linked prompt for SMB Chassis IP.
  #
  # check_ip procedure is used to validate XXX.XXX.XXX.XXX format of input
  # Link with valid IP reserving nothing
  ################################################################################
  proc linkSMB {} {
	if {[ETGetLinkStatus] < 0} {
     	#puts "SmartBits not linked - Enter chassis IP address"
     	#puts "The default target is 172.16.2.248.\n"
     	#puts "Press Enter key to accept:"
     	#gets stdin ipaddr
     	#if {[string equal $ipaddr ""]} {set ipaddr "172.16.2.248"}
     	set ipaddr "172.16.2.248"
     	puts "Connecting to $ipaddr"
     	set retval [NSSocketLink $ipaddr 16385 $::RESERVE_ALL]
     	if {$retval < 0 } {
          	puts "Unable to connect to $ipaddr. Please try again."
          	exit
     	}
     	puts "Connected to $ipaddr\n"
	
     	#if {[ETGetLinkStatus] < 1} {
         	#puts " Enter SmartBits chassis IP address: "
         	#gets stdin ipAddr
         	#NSSocketLink $ipAddr 16385 $::RESERVE_ALL
     	#}
	}
  }
  ################################################################################
  
  linkSMB

     	puts "Setting SmartLib to operate in native mode\n"
     	NSSetPortMappingMode $PORT_MAPPING_NATIVE
 
#Define Structures
struct_new StreamCount ULong
struct_new TxCounters HTCountStructure
struct_new RxCounters HTCountStructure


###########################################################################################
# Reset cards                                                                             #
###########################################################################################

puts "Resetting Tx and Rx cards ..."
LIBCMD HTResetPort $RESET_FULL $Hub $Slot1 $Port1
LIBCMD HTResetPort $RESET_FULL $Hub $Slot2 $Port2
LIBCMD HTResetPort $RESET_FULL $Hub $Slot2 $Port3

###########################################################################################
# Clear Counters                                                                          #
###########################################################################################

puts "Clearing counters for Tx and Rx cards ..."
LIBCMD HTClearPort $Hub $Slot1 $Port1
LIBCMD HTClearPort $Hub $Slot2 $Port2
LIBCMD HTClearPort $Hub $Slot2 $Port3

###########################################################################################
# Define First IP stream on Card 1.                                                        #
###########################################################################################

puts "Defining first IP stream ..."

#Declare IP stream structure
struct_new streamIP StreamIP

#Define IP stream contents
set streamIP(ucActive) 1
set streamIP(ucProtocolType) $STREAM_PROTOCOL_IP
set streamIP(uiFrameLength) $dataLength
set streamIP(TimeToLive) 10
set streamIP(Protocol) 4

#set streamIP(DestinationMAC) {1 1 1 1 1 1}
#set streamIP(DestinationMAC) {2 1 1 1 1 1}
#set streamIP(DestinationMAC) {3 1 1 1 1 1}
#set streamIP(DestinationMAC) {4 1 1 1 1 1}
#set streamIP(DestinationMAC) {5 1 1 1 1 1}
set streamIP(DestinationMAC) {6 4 1 1 1 1}
#set streamIP(DestinationMAC) {7 1 1 1 1 1}
#set streamIP(DestinationMAC) {8 1 1 1 1 1}
#set streamIP(DestinationMAC) {A 1 1 1 1 1}
#set streamIP(DestinationMAC) {B 1 1 1 1 1}
#set streamIP(DestinationMAC) {C 1 1 1 1 1}
#set streamIP(DestinationMAC) {D 1 1 1 1 1}
#set streamIP(DestinationMAC) {E 1 1 1 1 1}
#set streamIP(DestinationMAC) {F 1 1 1 1 1}
#
#set streamIP(SourceMAC) {1 1 1 1 1 1}
#set streamIP(SourceMAC) {2 1 1 1 1 1}
#set streamIP(SourceMAC) {3 1 1 1 1 1}
#set streamIP(SourceMAC) {4 1 1 1 1 1}
#set streamIP(SourceMAC) {5 1 1 1 1 1}
set streamIP(SourceMAC) {6 3 1 1 1 1}
#set streamIP(SourceMAC) {7 1 1 1 1 1}
#set streamIP(SourceMAC) {8 1 1 1 1 1}
#set streamIP(SourceMAC) {A 1 1 1 1 1}
#set streamIP(SourceMAC) {B 1 1 1 1 1}
#set streamIP(SourceMAC) {C 1 1 1 1 1}
#set streamIP(SourceMAC) {D 1 1 1 1 1}
#set streamIP(SourceMAC) {E 1 1 1 1 1}
#set streamIP(SourceMAC) {F 1 1 1 1 1}

set streamIP(DestinationIP) {172 16 202 1}
set streamIP(SourceIP) {172 16 201 1}

#Set Stream definition to the TX Card, starting at index 1, and delete streamIP structure.
LIBCMD HTSetStructure $L3_DEFINE_IP_STREAM 0 0 0 streamIP 0 $Hub $Slot1 $Port1
unset streamIP

###########################################################################################
# Define Second IP stream on Card 2.                                                        #
###########################################################################################

puts "Defining second IP stream ..."

#Declare IP stream structure
struct_new streamIP StreamIP

#Define IP stream contents
set streamIP(ucActive) 1
set streamIP(ucProtocolType) $STREAM_PROTOCOL_IP
set streamIP(uiFrameLength) $dataLength
set streamIP(TimeToLive) 10
set streamIP(Protocol) 4


#set streamIP(DestinationMAC) {1 1 1 1 1 1}
#set streamIP(DestinationMAC) {2 1 1 1 1 1}
#set streamIP(DestinationMAC) {3 1 1 1 1 1}
#set streamIP(DestinationMAC) {4 1 1 1 1 1}
#set streamIP(DestinationMAC) {5 1 1 1 1 1}
set streamIP(DestinationMAC) {6 3 1 1 1 1}
#set streamIP(DestinationMAC) {7 1 1 1 1 1}
#set streamIP(DestinationMAC) {8 1 1 1 1 1}
#set streamIP(DestinationMAC) {A 1 1 1 1 1}
#set streamIP(DestinationMAC) {B 1 1 1 1 1}
#set streamIP(DestinationMAC) {C 1 1 1 1 1}
#set streamIP(DestinationMAC) {D 1 1 1 1 1}
#set streamIP(DestinationMAC) {E 1 1 1 1 1}
#set streamIP(DestinationMAC) {F 1 1 1 1 1}
#
#set streamIP(SourceMAC) {1 1 1 1 1 1}
#set streamIP(SourceMAC) {2 1 1 1 1 1}
#set streamIP(SourceMAC) {3 1 1 1 1 1}
#set streamIP(SourceMAC) {4 1 1 1 1 1}
#set streamIP(SourceMAC) {5 1 1 1 1 1}
set streamIP(SourceMAC) {6 4 1 1 1 1}
#set streamIP(SourceMAC) {7 1 1 1 1 1}
#set streamIP(SourceMAC) {8 1 1 1 1 1}
#set streamIP(SourceMAC) {A 1 1 1 1 1}
#set streamIP(SourceMAC) {B 1 1 1 1 1}
#set streamIP(SourceMAC) {C 1 1 1 1 1}
#set streamIP(SourceMAC) {D 1 1 1 1 1}
#set streamIP(SourceMAC) {E 1 1 1 1 1}
#set streamIP(SourceMAC) {F 1 1 1 1 1}

set streamIP(DestinationIP) {172 16 201 1}
set streamIP(SourceIP) {172 16 202 1}

#Set Stream definition to the TX Card, starting at index 1, and delete streamIP structure.
LIBCMD HTSetStructure $L3_DEFINE_IP_STREAM 0 0 0 streamIP 0 $Hub $Slot2 $Port2
unset streamIP

###########################################################################################
# Define Second IP stream on Card 3.                                                        #
###########################################################################################

puts "Defining second IP stream ..."

#Declare IP stream structure
struct_new streamIP StreamIP

#Define IP stream contents
set streamIP(ucActive) 1
set streamIP(ucProtocolType) $STREAM_PROTOCOL_IP
set streamIP(uiFrameLength) $dataLength
set streamIP(TimeToLive) 10
set streamIP(Protocol) 4


#set streamIP(DestinationMAC) {1 1 1 1 1 1}
#set streamIP(DestinationMAC) {2 1 1 1 1 1}
#set streamIP(DestinationMAC) {3 1 1 1 1 1}
#set streamIP(DestinationMAC) {4 1 1 1 1 1}
#set streamIP(DestinationMAC) {5 1 1 1 1 1}
set streamIP(DestinationMAC) {6 3 1 1 1 1}
#set streamIP(DestinationMAC) {7 1 1 1 1 1}
#set streamIP(DestinationMAC) {8 1 1 1 1 1}
#set streamIP(DestinationMAC) {A 1 1 1 1 1}
#set streamIP(DestinationMAC) {B 1 1 1 1 1}
#set streamIP(DestinationMAC) {C 1 1 1 1 1}
#set streamIP(DestinationMAC) {D 1 1 1 1 1}
#set streamIP(DestinationMAC) {E 1 1 1 1 1}
#set streamIP(DestinationMAC) {F 1 1 1 1 1}
#
#set streamIP(SourceMAC) {1 1 1 1 1 1}
#set streamIP(SourceMAC) {2 1 1 1 1 1}
#set streamIP(SourceMAC) {3 1 1 1 1 1}
#set streamIP(SourceMAC) {4 1 1 1 1 1}
#set streamIP(SourceMAC) {5 1 1 1 1 1}
set streamIP(SourceMAC) {6 5 1 1 1 1}
#set streamIP(SourceMAC) {7 1 1 1 1 1}
#set streamIP(SourceMAC) {8 1 1 1 1 1}
#set streamIP(SourceMAC) {A 1 1 1 1 1}
#set streamIP(SourceMAC) {B 1 1 1 1 1}
#set streamIP(SourceMAC) {C 1 1 1 1 1}
#set streamIP(SourceMAC) {D 1 1 1 1 1}
#set streamIP(SourceMAC) {E 1 1 1 1 1}
#set streamIP(SourceMAC) {F 1 1 1 1 1}

set streamIP(DestinationIP) {172 16 201 1}
set streamIP(SourceIP) {172 16 203 1}

#Set Stream definition to the TX Card, starting at index 1, and delete streamIP structure.
LIBCMD HTSetStructure $L3_DEFINE_IP_STREAM 0 0 0 streamIP 0 $Hub $Slot2 $Port3
unset streamIP

###########################################################################################
#Define 9 more streams on TX card, based on the first stream.                             #
#Also, increment the Destination MAC address in each additional stream by 1.              #
#Therefore,                                                                               #
#The first stream has a Destination MAC address of 1 1 1 1 1 1 (as defined above);        #
#The second stream has a Destination MAC address of 1 1 1 1 1 2;                          #
#The third stream has a Destination MAC address of 1 1 1 1 1 3, etc..                     #
###########################################################################################

#puts "Defining 9 more IP Streams ..."

#Declare IP stream structure
struct_new streamIP StreamIP

#Define IP fields wish to increment, and the value to increment by.
set streamIP(DestinationMAC) {0 0 0 0 0 1}
set streamIP(SourceMAC) {0 0 0 0 0 1}
set streamIP(SourceIP) {0 0 0 1}
set streamIP(DestinationIP) {0 0 0 1}

set numberOfStreams 1000
#Copy numberOfStreams  more IP streams to the TX Card, based on the first stream, and delete stream structure.
LIBCMD HTSetStructure $L3_DEFINE_MULTI_IP_STREAM 1 $numberOfStreams 0 streamIP 0 $Hub $Slot1 $Port1
LIBCMD HTSetStructure $L3_DEFINE_MULTI_IP_STREAM 1 $numberOfStreams 0 streamIP 0 $Hub $Slot2 $Port2
LIBCMD HTSetStructure $L3_DEFINE_MULTI_IP_STREAM 1 $numberOfStreams 0 streamIP 0 $Hub $Slot2 $Port3
unset streamIP

    # force speed to 10 MHz
  #LIBCMD HTSetSpeed $SPEED_10MHZ $Hub $Slot1 $Port1
  #LIBCMD HTSetSpeed $SPEED_10MHZ $Hub $Slot2 $Port2

    # force speed to 100 MHz
 # LIBCMD HTSetSpeed $SPEED_100MHZ $Hub $Slot1 $Port1
  #LIBCMD HTSetSpeed $SPEED_100MHZ $Hub $Slot2 $Port2
  
    # start transmitting should be full rate for 100 | 96 bit times is minimum gap
 # LIBCMD HTGap 96 $Hub $Slot1 $Port1
  #LIBCMD HTGap 96 $Hub $Slot2 $Port2
  #puts "Transmitting at 100% should be 148,810 pps at 60 byte data length"
  #LIBCMD HTRun $HTRUN $Hub $Slot1 $Port1
  #LIBCMD HTRun $HTRUN $Hub $Slot2 $Port2
  #after 4000
  #displayCount $Hub $Slot1 $Port1
  #displayCount $Hub $Slot2 $Port2
  #HTRun $HTSTOP $Hub $Slot1 $Port1
  #HTRun $HTSTOP $Hub $Slot2 $Port2
  
    # switch rate to pps - use function return as argument to HTGap command
  puts "Setting rate to $framesPerSecond"
  LIBCMD HTGap [setFramesPerSecond $Hub $Slot1 $Port1 $speed $dataLength $framesPerSecond] $Hub $Slot1 $Port1
  LIBCMD HTGap [setFramesPerSecond $Hub $Slot2 $Port2 $speed $dataLength $framesPerSecond] $Hub $Slot2 $Port2
  #LIBCMD HTGap [setFramesPerSecond $Hub $Slot2 $Port3 $speed $dataLength $framesPerSecond] $Hub $Slot2 $Port3
  puts "Transmitting at $framesPerSecond frames per second"
  LIBCMD HTRun $HTRUN $Hub $Slot1 $Port1
  LIBCMD HTRun $HTRUN $Hub $Slot2 $Port2
 # LIBCMD HTRun $HTRUN $Hub $Slot2 $Port3
 # after 80000000
  after 100000
  displayCount $Hub $Slot1 $Port1
  displayCount $Hub $Slot2 $Port2
 # displayCount $Hub $Slot2 $Port3
  HTRun $HTSTOP $Hub $Slot1 $Port1
  HTRun $HTSTOP $Hub $Slot2 $Port2
 # HTRun $HTSTOP $Hub $Slot2 $Port3
  
    # switch load 
  #puts "Setting load to $loadPerCent percent"
  #LIBCMD HTGap [setLoad $Hub $Slot1 $Port1 $speed $dataLength $loadPerCent] $Hub $Slot1 $Port1
  #LIBCMD HTGap [setLoad $Hub $Slot2 $Port2 $speed $dataLength $loadPerCent] $Hub $Slot2 $Port2
  #puts "Transmitting at $loadPerCent percent load"
  #LIBCMD HTRun $HTRUN $Hub $Slot1 $Port1
  #LIBCMD HTRun $HTRUN $Hub $Slot2 $Port2
  #after 4000
  #displayCount $Hub $Slot1 $Port1
  #displayCount $Hub $Slot2 $Port2
  #HTRun $HTSTOP $Hub $Slot1 $Port1
  #HTRun $HTSTOP $Hub $Slot2 $Port2
  
 ETUnLink
